package com.example.foodsy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.foodsy.dto.*;
import com.example.foodsy.entity.*;
import com.example.foodsy.mapper.*;
import com.example.foodsy.service.CityService;
import com.example.foodsy.service.ProvinceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TraceQueryServiceImpl {
    @Autowired
    private RetaInfoMapper retaBatchMapper;
    @Autowired
    private WholInfoMapper wholBatchMapper;
    @Autowired
    private SlauInfoMapper slauBatchMapper;
    @Autowired
    private FarmInfoMapper farmBatchMapper;
    @Autowired
    private CompanyInfoMapper nodeInfoMapper;

    /**
     * 按溯源码查询全流通环节
     */
    public TraceFullDTO queryFullTraceBySourceId(String sourceId) {
        // 1. 查询零售环节（reta_batch + 零售商信息）
        RetaInfo retaBatch = retaBatchMapper.selectOne(
            new LambdaQueryWrapper<RetaInfo>().eq(RetaInfo::getSourceId, sourceId)
        );
        if (retaBatch == null) {
            return null;
        }
        CompanyInfo retaNode = nodeInfoMapper.selectById(retaBatch.getRetaId());
        TraceRetailDTO retailDTO = this.convertToRetailDTO(retaBatch, retaNode);

        // 2. 查询批发环节（whol_batch + 批发商信息）
        WholInfo wholBatch = wholBatchMapper.selectById(retaBatch.getWbId());
        CompanyInfo wholNode = wholBatch != null ? nodeInfoMapper.selectById(wholBatch.getWholId()) : null;
        TraceWholesaleDTO wholesaleDTO = this.convertToWholesaleDTO(wholBatch, wholNode);

        // 3. 查询屠宰环节（slau_batch + 屠宰企业信息）
        SlauInfo slauBatch = wholBatch != null ? slauBatchMapper.selectById(wholBatch.getSbId()) : null;
        CompanyInfo slauNode = slauBatch != null ? nodeInfoMapper.selectById(slauBatch.getSlauId()) : null;
        TraceSlaughterDTO slaughterDTO = this.convertToSlaughterDTO(slauBatch, slauNode);

        // 4. 查询养殖环节（farm_batch + 养殖企业信息）
        FarmInfo farmBatch = slauBatch != null ? farmBatchMapper.selectById(slauBatch.getFbId()) : null;
        CompanyInfo farmNode = farmBatch != null ? nodeInfoMapper.selectById(farmBatch.getFarmId()) : null;
        TraceBreedDTO breedDTO = this.convertToBreedDTO(farmBatch, farmNode);

        // 5. 封装全环节DTO返回
        TraceFullDTO fullDTO = new TraceFullDTO();
        fullDTO.setBreed(breedDTO);
        fullDTO.setSlaughter(slaughterDTO);
        fullDTO.setWholesale(wholesaleDTO);
        fullDTO.setRetail(retailDTO);
        fullDTO.setSourceId(sourceId);
        return fullDTO;
    }


    // 注入省/市查询服务（需提前实现ProvinceService/CityService，按ID查名称）
    @Autowired
    private ProvinceService provinceService;
    @Autowired
    private CityService cityService;

    /**
     * 养殖批次+养殖企业 → 养殖环节DTO
     * @param farmBatch 养殖批次表数据（farm_batch）
     * @param farmNode 养殖企业表数据（node_info，type=1）
     * @return 养殖环节DTO（空值返回null）
     */
    private TraceBreedDTO convertToBreedDTO(FarmInfo farmBatch, CompanyInfo farmNode) {
        // 1. 非空校验：批次或企业数据为空，直接返回null
        if (farmBatch == null || farmNode == null) {
            return null;
        }

        // 2. 初始化DTO并映射字段
        TraceBreedDTO breedDTO = new TraceBreedDTO();
        // 企业相关字段（来自node_info）
        breedDTO.setBreedCompanyName(farmNode.getName());
        breedDTO.setBreedCompanyAddress(farmNode.getAddress());
        // 批次相关字段（来自farm_batch）
        breedDTO.setBatchId(farmBatch.getBatchId());
        breedDTO.setProductType(farmBatch.getFarmType());
        breedDTO.setAnimalQuarantineCert(farmBatch.getAqcId());
        breedDTO.setQuarantineOfficer(farmBatch.getTestName());
        breedDTO.setBatchDate(farmBatch.getFmDate());

        // 3. 拼接产地（省名+市名，来自province/city表）
        String provinceName = provinceService.getById(farmNode.getProvId()).getProvName();
        String cityName = cityService.getById(farmNode.getCityId()).getCityName();
        breedDTO.setOrigin(provinceName + " " + cityName);

        return breedDTO;
    }

    /**
     * 屠宰批次+屠宰企业+关联养殖批次 → 屠宰环节DTO
     * @param slauBatch 屠宰批次表数据（slau_batch）
     * @param slauNode 屠宰企业表数据（node_info，type=2）
     * @return 屠宰环节DTO（空值返回null）
     */
    private TraceSlaughterDTO convertToSlaughterDTO(SlauInfo slauBatch, CompanyInfo slauNode) {
        if (slauBatch == null || slauNode == null) {
            return null;
        }

        TraceSlaughterDTO slaughterDTO = new TraceSlaughterDTO();
        // 企业相关字段（来自node_info）
        slaughterDTO.setSlaughterCompanyName(slauNode.getName());
        slaughterDTO.setSlaughterCompanyAddress(slauNode.getAddress());
        // 批次相关字段（来自slau_batch）
        slaughterDTO.setBatchId(slauBatch.getBatchId());
        slaughterDTO.setProductType(slauBatch.getType());
        slaughterDTO.setMeatQuarantineCert(slauBatch.getQuaId());
        slaughterDTO.setInspectorName(slauBatch.getTestName());
        slaughterDTO.setBatchDate(slauBatch.getBatchDate());

        // 4. 关联养殖批次（展示溯源链路，来自slau_batch.fb_id关联的farm_batch）
        FarmInfo sourceFarmBatch = farmBatchMapper.selectById(slauBatch.getFbId());
        if (sourceFarmBatch != null) {
            slaughterDTO.setSourceBreedBatchId(sourceFarmBatch.getBatchId());
        }

        // 5. 拼接产地（省名+市名）
        String provinceName = provinceService.getById(slauNode.getProvId()).getProvName();
        String cityName = cityService.getById(slauNode.getCityId()).getCityName();
        slaughterDTO.setOrigin(provinceName + " " + cityName);

        return slaughterDTO;
    }

    /**
     * 批发批次+批发商+关联屠宰批次 → 批发环节DTO
     * @param wholBatch 批发批次表数据（whol_batch）
     * @param wholNode 批发商表数据（node_info，type=3）
     * @return 批发环节DTO（空值返回null）
     */
    private TraceWholesaleDTO convertToWholesaleDTO(WholInfo wholBatch, CompanyInfo wholNode) {
        if (wholBatch == null || wholNode == null) {
            return null;
        }

        TraceWholesaleDTO wholesaleDTO = new TraceWholesaleDTO();
        // 企业相关字段（来自node_info）
        wholesaleDTO.setWholesaleCompanyName(wholNode.getName());
        wholesaleDTO.setWholesaleCompanyAddress(wholNode.getAddress());
        // 批次相关字段（来自whol_batch）
        wholesaleDTO.setBatchId(wholBatch.getBatchId());
        wholesaleDTO.setProductType(wholBatch.getType());
        wholesaleDTO.setBatchDate(wholBatch.getBatchDate());

        // 4. 关联屠宰批次（展示溯源链路，来自whol_batch.sb_id关联的slau_batch）
        SlauInfo sourceSlauBatch = slauBatchMapper.selectById(wholBatch.getSbId());
        if (sourceSlauBatch != null) {
            wholesaleDTO.setSourceSlaughterBatchId(sourceSlauBatch.getBatchId());
        }

        // 5. 拼接产地（省名+市名）
        String provinceName = provinceService.getById(wholNode.getProvId()).getProvName();
        String cityName = cityService.getById(wholNode.getCityId()).getCityName();
        wholesaleDTO.setOrigin(provinceName + " " + cityName);

        return wholesaleDTO;
    }

    /**
     * 零售批次+零售商+关联批发批次 → 零售环节DTO（含溯源码）
     * @param retaBatch 零售批次表数据（reta_batch，需state=3已确认，含source_id）
     * @param retaNode 零售商表数据（node_info，type=4）
     * @return 零售环节DTO（空值返回null）
     */
    private TraceRetailDTO convertToRetailDTO(RetaInfo retaBatch, CompanyInfo retaNode) {
        if (retaBatch == null || retaNode == null) {
            return null;
        }

        TraceRetailDTO retailDTO = new TraceRetailDTO();
        // 企业相关字段（来自node_info）
        retailDTO.setRetailCompanyName(retaNode.getName());
        retailDTO.setRetailCompanyAddress(retaNode.getAddress());
        // 批次相关字段（来自reta_batch，含任务书核心的溯源码）
        retailDTO.setBatchId(retaBatch.getBatchId());
        retailDTO.setProductType(retaBatch.getType());
        retailDTO.setSourceId(retaBatch.getSourceId()); // 溯源标识码，任务书3.2.6.6核心
        retailDTO.setBatchDate(retaBatch.getBatchDate());

        // 4. 关联批发批次（展示溯源链路，来自reta_batch.wb_id关联的whol_batch）
        WholInfo sourceWholBatch = wholBatchMapper.selectById(retaBatch.getWbId());
        if (sourceWholBatch != null) {
            retailDTO.setSourceWholesaleBatchId(sourceWholBatch.getBatchId());
        }

        // 5. 拼接产地（省名+市名）
        String provinceName = provinceService.getById(retaNode.getProvId()).getProvName();
        String cityName = cityService.getById(retaNode.getCityId()).getCityName();
        retailDTO.setOrigin(provinceName + " " + cityName);

        return retailDTO;
    }
}